using System;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using Mono.Security.Cryptography;

namespace Ufaev.Cryptography
{
	/// <summary>
	/// Accesses the managed version of the GOST 28147-89 algorithm. This class cannot be inherited.
	/// </summary>
	[ComVisible(true)]
	public sealed class Gost28147Managed : Gost28147
	{
		#region Constructors

		/// <summary>
		/// Initializes a new instance of the <see cref="Gost28147Managed"/> class.
		/// </summary>
		public Gost28147Managed()
		{
		}

		#endregion Constructors

		#region Overriden Methods

		/// <summary>
		/// Generates a random initialization vector (IV) to be used for the algorithm.
		/// </summary>
		/// <remarks>Use this method to generate a random IV when none is specified.</remarks>
		public override void GenerateIV()
		{
			IVValue = KeyBuilder.IV(BlockSizeValue >> 3);
		}

		/// <summary>
		/// Generates a random key to be used for the algorithm.
		/// </summary>
		/// <remarks>Use this method to generate a random key when none is specified.</remarks>
		public override void GenerateKey()
		{
			KeyValue = KeyBuilder.Key(KeySizeValue >> 3);
		}

		/// <summary>
		/// Creates a symmetric decryptor object with the specified key and initialization vector (IV).
		/// </summary>
		/// <param name="rgbKey">The secret key to be used for the symmetric algorithm. The key size must be 256 bits.</param>
		/// <param name="rgbIV">The IV to be used for the symmetric algorithm.</param>
		/// <remarks>This method decrypts an encrypted message created using the <see cref="CreateEncryptor"/> overload with the same signature.</remarks>
		/// <returns>A symmetric decryptor object.</returns>
		public override ICryptoTransform CreateDecryptor(byte[] rgbKey, byte[] rgbIV)
		{
			return new Gost28147Transform(this, false, rgbKey, rgbIV);
		}

		/// <summary>
		/// Creates a symmetric encryptor object with the specified key and initialization vector (IV).
		/// </summary>
		/// <param name="rgbKey">The secret key to be used for the symmetric algorithm. The key size must be 256 bits.</param>
		/// <param name="rgbIV">The IV to be used for the symmetric algorithm.</param>
		/// <remarks>
		/// Use the <see cref="CreateDecryptor"/> overload with the same signature to decrypt the result of this method.
		/// </remarks>
		/// <returns>A symmetric encryptor object.</returns>
		public override ICryptoTransform CreateEncryptor(byte[] rgbKey, byte[] rgbIV)
		{
			return new Gost28147Transform(this, true, rgbKey, rgbIV);
		}

		#endregion Overriden Methods
	}
}
